今日主題是透過 TodoList 來學習
this 是我的 that 還是窗戶Todo List - codepen
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
  close[i].onclick = function() {
    var div = this.parentElement;
    div.style.display = "none";
  }
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
  if (ev.target.tagName === 'LI') {
    ev.target.classList.toggle('checked');
  }
}, false);
<span class="close">x<span>
getElementsByClassName 取得符合 class 等於 close 的 HTMLCollection
close element 都給個 onclick 的 anonymous function
function 出現了 this,而這個 this 居然是 close[i] 那一個 node 這邊稍作一點說明在 javascript 中 this 通常指的是呼叫該 method 的人,而非該 method的物件本身,例如當 close[0] 被點擊了,底層的十之八九是 close[0].onclick(e) 來執行這個 function 那這個 this 就會指向 close[0],所以通常給 Node event function 會利用這個特性直接使用 this 來操作該節點
如果試試看改成這樣會發生什麼事呢?
  close[i].onclick = function() {
    var div = this.parentElement;
    div.style.display = "none";
  }
  var myImmediateEvent = close[i].close;
  myImmediateEvent();
會發現 this 壞掉了,而 console 的 error 說的是 undefined 沒有 style 的 property
原因是呼叫 myImmediateEvent 沒有主人,順其自然就是最外層的呼叫 myImmediateEvent 了
而 window 上的 property 沒有 parentElement 這個 property 所以頁面就壞掉啦~
假設 window 有這個 property 其實更危險,因為可能改動到其他 module 的功能。
this 的原理可以詳讀
// Create a new list item when clicking on the "Add" button
function addTodo() {
  var li = document.createElement("li");
  var inputValue = document.getElementById("todo-input").value;
  var t = document.createTextNode(inputValue);
  li.appendChild(t);
  if (inputValue === '') {
    alert("請輸入待辦事項");
  } else {
    document.getElementById("todo-list").appendChild(li);
  }
  document.getElementById("todo-input").value = "";
  var span = document.createElement("SPAN");
  var txt = document.createTextNode("x");
  span.className = "close";
  span.appendChild(txt);
  li.appendChild(span);
  for (i = 0; i < close.length; i++) {
    close[i].onclick = function() {
      var div = this.parentElement;
      div.style.display = "none";
    }
  }
}
最後是這一段 addTodo function 的代碼
這邊的流程就是
<li></li> 的 element然後加到 div#todo-list 後面<span>x</span> 加到 #1 創建的 li 之後close 這個 HTMLCollection 的參數設定 onclick method如果有看昨天的說明就會了解 live 的 HTMLCollection 原理,所以這個 addTodo function 才能這樣子跑
有沒有覺得很奇怪,第一段代碼的地方 <span>x</span> 這個節點是用 span.innerHTML="x" 加上去的,但這段代碼的 span 上的 x 和 li 的文字是用 createTextNode
我覺得這段 javascript 很容易踩到雷,所以要小心
同樣先看 MDN 好像沒有特別講
不過意思是說你輸入的文字都會幫你加到節點裡
而 innerHTML 會把輸入的文字變成 HTML ,然後就有可能被使用者用文字攻擊囉~
試試這段代碼
var child = document.createElement('div')
child.innerHTML = '<div></div>'
console.log(child)
所以記得要小心使用 innerHTML
到目前為只有看到三種 click event 的寫法,想必大家也很好奇其中的奧妙,明天來看看 event 的部分吧!